import { GMStorage } from '../../../lib/abstract'
import { logger } from '../../../types/constants'

export class SelectorUpdateTimeMap extends GMStorage {
  id: string = 'selector-update-times'
  name: string = 'SelectorUpdateTimeMap'
  private storageKey = 'selector-update-times'
  private map: Map<string, number>
  private static instance: SelectorUpdateTimeMap

  constructor() {
    super()
    this.map = new Map(JSON.parse(
      this.storage.get(this.storageKey, '[]'),
    ))
  }

  /**
   * 获取单例实例
   */
  public static getInstance(): SelectorUpdateTimeMap {
    if (!SelectorUpdateTimeMap.instance) {
      SelectorUpdateTimeMap.instance = new SelectorUpdateTimeMap()
    }
    return SelectorUpdateTimeMap.instance
  }

  get(selector: string): number {
    return this.map.get(selector) || 0
  }

  set(selector: string, time: number = Date.now()): void {
    this.map.set(selector, time)
    this.persist()
  }

  private persist() {
    this.storage.set(
      this.storageKey,
      JSON.stringify(Array.from(this.map.entries())),
    )
  }
}

interface StyleIdMapping {
  id: string // 原始选择器ID
  property: string // 样式属性
  createTime: number // 创建时间戳
}
export class StyleIdManager extends GMStorage {
  id: string = 'selector-ids'
  name: string = 'StyleIdManager'
  private readonly PREFIX = {
    forward: 'style-map:',
    reverse: 'reverse-map:',
  }

  private static instance: StyleIdManager

  /**
   * 获取单例实例
   */
  public static getInstance(): StyleIdManager {
    if (!StyleIdManager.instance) {
      StyleIdManager.instance = new StyleIdManager()
    }
    return StyleIdManager.instance
  }

  /**
   * 生成/获取样式ID
   */
  getStyleId(id: string, property: string): string {
    const key = `${this.PREFIX.forward}${id}_${property}`
    let styleId = this.storage.get(key) as string

    if (!styleId) {
      styleId = this.generateId()
      this.storage.set(key, styleId)
      this.setReverseMapping(styleId, id, property)
    }

    return styleId
  }

  /**
   * 反向查询原始ID
   */
  getOriginalId(styleId: string, property?: string): string | null {
    const mapping = this.storage.get(`${this.PREFIX.reverse}${styleId}`) as StyleIdMapping
    return mapping && (!property || mapping.property === property)
      ? mapping.id
      : null
  }

  private generateId(): string {
    return Math.random().toString(36).slice(2, 10) // 8位随机ID
  }

  setReverseMapping(styleId: string, id: string, property: string): void {
    this.storage.set(`${this.PREFIX.reverse}${styleId}`, {
      id,
      property,
      createTime: Date.now(),
    })
  }

  /**
   * 清理样式ID映射关系
   * @param styleId 需要清理的样式ID
   */
  clearMapping(styleId: string): boolean {
    try {
    // 1. 获取反向映射数据
      const mapping = this.storage.get(
        `${this.PREFIX.reverse}${styleId}`,
      ) as StyleIdMapping | undefined

      if (!mapping) {
        logger.warn(`[${this.id}] 未找到 styleId ${styleId}的映射记录`)
        return false
      }

      // 2. 清理正向索引 (id+property → styleId)
      const forwardKey = `${this.PREFIX.forward}${mapping.id}_${mapping.property}`
      this.storage.delete(forwardKey)

      // 3. 清理反向索引 (styleId → mapping)
      this.storage.delete(`${this.PREFIX.reverse}${styleId}`)

      logger.info(`[${this.id}] 已清理映射: ${styleId} => ${mapping.id}.${mapping.property}`)
      return true
    }
    catch (error: any) {
      logger.error(`[${this.id}] 清理映射失败:`, error)
      return false
    }
  }
}
